package com.qf.driver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.qf.common.bean.R;
import com.qf.common.dto.DeviceTopicDto;
import com.qf.common.model.QfDeviceTopic;
import com.qf.driver.feign.DeviceTopicFeign;
import com.qf.driver.mqtt.bean.MqttProperties;
import com.qf.driver.service.DeviceTopicService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 千锋健哥
 */
@Service
@Slf4j
public class DeviceTopicServiceImpl implements DeviceTopicService, BeanFactoryAware {

    @Autowired
    private DeviceTopicFeign deviceTopicFeign;

    @Autowired
    private MqttProperties mqttProperties;

    /**
     * 想要获取MqttConfig初始化类中的mqttInbound对象, 但是无法注入
     * 所有实现Spring中的BeanFactoryAware接口
     * 直接从Spring容器中获取BeanFactory工厂对象, 从BeanFactory工厂对象中获取mqttInbound对象
     */
    private BeanFactory beanFactory;

    @Override
    public void deviceTopicJoin(String deviceKey) {
        //1. 根据设备key查询对应的topic主题列表, 一个设备是一对topic主题
        DeviceTopicDto topicDto = new DeviceTopicDto();
        topicDto.setDeviceKey(deviceKey);
        R<List> topicResult = deviceTopicFeign.findAll(topicDto);
        if (topicResult.getData() == null || topicResult.getData().size() == 0) {
            log.info("[driver-mqtt设备中心]设备连接中, 认证失败, 原因: 设备对应的主题topic不存在, deviceKey==={}", deviceKey);
            return;
        }

        //2. 从mqttconfig初始化类中获取对应的主题订阅对象
        Object mqttInbound = beanFactory.getBean("mqttInbound");
        //强转为mqtt通道对象
        MqttPahoMessageDrivenChannelAdapter mqttChannel = (MqttPahoMessageDrivenChannelAdapter)mqttInbound;
        //遍历获取到的topic列表
        try {
            for (Object topicData : topicResult.getData()) {
                //类型转换
                QfDeviceTopic deviceTopic = BeanUtil.toBean(topicData, QfDeviceTopic.class);
                //3. 将topic主题名称, 加入到mqtt通道中, 进行连接
                mqttChannel.addTopic(deviceTopic.getTopic(), mqttProperties.getQos());
            }
        } catch (Exception e) {
            //throw new RuntimeException(e);
        }

    }

    @Override
    public List<QfDeviceTopic> findTopicAll() {
        //查询对应的topic主题列表, 一个设备是一对topic主题
        DeviceTopicDto topicDto = new DeviceTopicDto();
        R<List> topicResult = deviceTopicFeign.findAll(topicDto);
        if (topicResult.getData() == null || topicResult.getData().size() == 0) {
            log.info("[driver-mqtt设备中心]设备不存在topic主题");
            return null;
        }
        List<QfDeviceTopic>  list = new ArrayList<>();
        for (Object data : topicResult.getData()) {
            //类型转换
            list.add(BeanUtil.toBean(data, QfDeviceTopic.class));
        }
        return list;
    }

    @Override
    public List<QfDeviceTopic> findTopicByDeviceKey(String deviceKey) {
        //查询对应的topic主题列表, 一个设备是一对topic主题
        DeviceTopicDto topicDto = new DeviceTopicDto();
        topicDto.setDeviceKey(deviceKey);
        R<List> topicResult = deviceTopicFeign.findAll(topicDto);
        if (topicResult.getData() == null || topicResult.getData().size() == 0) {
            log.info("[driver-mqtt设备中心]设备不存在topic主题");
            return null;
        }
        List<QfDeviceTopic>  list = new ArrayList<>();
        for (Object data : topicResult.getData()) {
            //类型转换
            list.add(BeanUtil.toBean(data, QfDeviceTopic.class));
        }
        return list;
    }

    /**
     * 使用set方法注入BeanFactory工厂对象
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

}
